#ifndef _HTTPIMPL_H_
#define _HTTPIMPL_H_

#include "stdafx.h"
#include <io/iframe.h>
#include <http/ihttp.h>
#include <net/idns.h>
#include "http/chttpparser.h"

class CHttptImpl :	public	IHttp_t,
					public  IIoOperationEvents,
					public	IDnsProc,
					public	CUnknownImp,
					public	CHttpParser
{
public:
	CHttptImpl();
	virtual ~CHttptImpl(void);
public:
	void BindHttp(IBase* pIAsyncTcpSocket, IBase* pIOper, IBase* pIDns);
	UNKNOWN_IMP1(IHttp_t);

	//////////////////////////////////////////////////////////////////////////
	//IHttp
	std_method(SetCookies)(http_header_data *data);
	std_method(SetNotify)(IHttpNotify *Notify);
	std_method(Perform)(ip_addr_s url, http_addr_s scheme, ip_port uport);
	std_method_(http_header, GetHttpHead)();
	std_method(ReSet)();
	std_method(Cancel)();
	std_method_(int, IsComplete)();
	//////////////////////////////////////////////////////////////////////////
	//IIoOperationEvents
	std_method(OnOperationComplete)(IIoOperation *pOperation);
	//////////////////////////////////////////////////////////////////////////

	//////////////////////////////////////////////////////////////////////////
	//IDnsProc
	std_method(DnsResultIP)(int error, const char* url, const char* ip);
	//////////////////////////////////////////////////////////////////////////
private:
	ULONG Notify(ULONG ulevent);
	ULONG Id_Suc(ULONG ulid);
	ULONG Id_Faild(ULONG ulid);
	ULONG sockInit(IAsyncTcpSocket* pIAsyncTcpSocket,ULONG sbuflen, ULONG rbuflen 
		,int iwtimout, int irtimout, int iconntimout);
private:
	std_method_impl httpEventProc(ULONG ulevent, IIoOperation *pOperation);
	std_method_impl httpConnected(IIoOperation *pOperation);
	std_method_impl httpSendHeaded(IIoOperation *pOperation);
	std_method_impl httpSendBodyed(IIoOperation *pOperation);
	std_method_impl httpRecvHeaded(IIoOperation *pOperation);
	std_method_impl httpRecvBodyed(IIoOperation *pOperation);
	std_method_impl httpEvent(ULONG ulevent, IIoDevice* pIoDevice, IIoOperation *pOperation);
	std_method_impl httpEventComplate(IIoDevice* pIoDevice, IIoOperation *pOperation);
private:
	std_method_impl httpConnect(IIoOperation *pOperation, ip_addr_s addr, ip_port uport);
	std_method_impl httpSendHead(IIoDevice* pIoDevice, IIoOperation *pOperation);
	std_method_impl httpSendBody(IIoDevice* pIoDevice, IIoOperation *pOperation);
	std_method_impl httpRecvHead(IIoDevice* pIoDevice, IIoOperation *pOperation);
	std_method_impl httpRecvBody(IIoDevice* pIoDevice, IIoOperation *pOperation);
	std_method_impl httpSend(ULONG uid, IIoDevice* pIoDevice, IIoOperation *pOperation);
	std_method_impl httpRecv(ULONG uid, IIoDevice* pIoDevice, IIoOperation *pOperation);

private:
	void on_http_message_begin();
	void on_http_header_complete();
	void on_http_body(const char* at, size_t length);
	void on_http_message_complete();
	
private:
	std_method_impl OnConnect(ip_addr_s url, ip_port uport);
	std_method_impl OnBuildHttp(ip_addr_s url, http_addr_s scheme, ip_port uport);

private:

private:
	_lComPtr<IAsyncTcpSocket>			m_pIAsyncTcpSocket;
	_lComPtr<IIoOperation>				m_pIOper;
	_lComPtr<IDns>						m_pIDns;

	os_int64							m_httpcontent_length;
	sentry<char*, default_array_sentry>	m_szhttpHead;
	sentry<char*, default_array_sentry>	m_szhttpSendHead;
	sentry<char*, default_array_sentry>	m_szhttpurl;

	ip_port								m_uport;
	///////////////////////////////////////////////////////////////
	IHttpNotify*						m_Notify;
	///////////////////////////////////////////////////////////////
	http_header_t						m_http_resheader;
	long								m_hstid;
};


#endif